package com.bestcem.xm.txtanls.retry;

import com.bestcem.xm.common.core.exception.BusinessException;
import com.bestcem.xm.txtanls.dao.AnalysisProjectDao;
import com.bestcem.xm.txtanls.enums.AnalysisStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

import static com.bestcem.xm.common.core.constant.Constants.*;

/**
 * mongo超时重试调用
 *
 * @author gy.liu
 * @version 1.0
 * @date 2021/5/17 17:27
 **/
@Slf4j
@Service
public class UpdateProjectStatusSpringRetry {
    private static final Logger EMAIL_LOG = LoggerFactory.getLogger("EmailErrorLog");

    @Resource
    private AnalysisProjectDao analysisProjectDao;

    public int updateProjectStatus(String projectId, AnalysisStatusEnum status) {

        // 表示哪些异常需要重试,key表示异常的字节码,value为true表示需要重试
        Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>(DEFAULT_MAP_SIZE);
        exceptionMap.put(Exception.class, true);
        // 构建重试模板实例
        RetryTemplate retryTemplate = new RetryTemplate();

        // 设置重试回退操作策略，主要设置重试间隔时间
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(FIXED_PERIOD_TIME);

        //设置重试次数和异常类型
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(MAX_RETRY_TIME, exceptionMap);

        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        try {
            return retryTemplate.execute(
                    // RetryCallback
                    retryContext -> {
                        if (log.isInfoEnabled()) {
                            log.info("[Txtanls] Retry-文本分析项目状态更新开始: {}", projectId);
                        }
                        //训练之后更新项目状态
                        int updateResult = analysisProjectDao.updateAnalysisProjectStatus(projectId, status.getIndex());
                        if (updateResult == 0) {
                            throw new BusinessException("");
                        }
                        if (log.isInfoEnabled()) {
                            log.info("[Txtanls] Retry-文本分析项目状态更新成功: {}", projectId);
                        }
                        return updateResult;
                    },

                    // RecoveryCallback
                    recoveryContext -> {
                        String errorMessage = recoveryContext.getLastThrowable().getMessage();
                        log.error("[Txtanls] Retry-文本分析项目状态更新失败; ErrorMessage: {}", errorMessage);
                        EMAIL_LOG.error("[Txtanls] Retry-文本分析项目状态更新失败; ErrorMessage: {}", errorMessage);
                        return 0;
                    }
            );
        } catch (BusinessException e) {
            return 0;
        }
    }
}